﻿#include "core/app_interface.h"

#define MSG_APP_PREINIT 1
#define MSG_APP_INIT 2
#define MSG_APP_RUN 3

namespace vz {

template <class T>
class MessageResult : public MessageData {
 public:
  T result_;
};

AppInterface::AppInterface(const std::string& app_name):
  app_name_(app_name),
  event_(true, false) {

}

std::string AppInterface::GetAppName() {
  return app_name_;
}

void AppInterface::SetEventService(EventService::Ptr event_service) {
  event_service_ = event_service;
}

EventService::Ptr AppInterface::GetEventService() {
  return event_service_;
}

bool AppInterface::PreInit() {
  MessageResult<bool> *data(new MessageResult<bool>);
  event_service_->Post(this, MSG_APP_PREINIT, data);
  event_.Wait(kForever);
  bool ret = data->result_;
  delete data;
  data = NULL;
  return ret;
}

bool AppInterface::Init() {
  MessageResult<bool> *data(new MessageResult<bool>);
  event_service_->Post(this, MSG_APP_INIT, data);
  event_.Wait(kForever);
  bool ret = data->result_;
  delete data;
  data = NULL;
  return ret;
}

bool AppInterface::Run() {
  MessageResult<bool> *data(new MessageResult<bool>);
  event_service_->Post(this, MSG_APP_RUN, data);
  event_.Wait(kForever);
  bool ret = data->result_;
  delete data;
  data = NULL;
  return ret;
}

void AppInterface::OnMessage(Message* msg) {
  switch (msg->message_id) {
  case MSG_APP_PREINIT: {
    bool ret = OnPreInit();
    MessageResult<bool> *data = (MessageResult<bool> *)msg->pdata;
    data->result_ = ret;
    event_.Set();
    break;
  }
  case MSG_APP_INIT: {
    bool ret = OnInit();
    MessageResult<bool> *data = (MessageResult<bool> *)msg->pdata;
    data->result_ = ret;
    event_.Set();
    break;
  }
  case MSG_APP_RUN: {
    bool ret = OnRun();
    MessageResult<bool> *data = (MessageResult<bool> *)msg->pdata;
    data->result_ = ret;
    event_.Set();
    break;
  }
  default:
    OnAppMessage(msg);
    break;
  }
}

}  // namespace vz
